# name_completer.py
import asyncio
import json
from config import Config
from db import DB
from ai_client import AIClientAsync
import logging
import time
import re
from openai import APIStatusError
import datetime  # 导入 datetime


# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 定义全局的 system message
SYSTEM_MESSAGE = "你是一个专业的起名大师，负责根据用户的要求提供详细的名字解析."


class NameCompleter:
    def __init__(self, config: Config, db: DB, ai_client: AIClientAsync):
        self.config = config
        self.db = db
        self.ai_client = ai_client
        self.semaphore = asyncio.Semaphore(config.MAX_CONCURRENCY)

    async def complete_details(self, surname=None, length=None, style=None, start_id=None):  # 添加 start_id 参数
        logging.info("开始补全名字详情...")
        while True:
             # 构建查询条件
            where_clauses = ["is_ready = 0"]
            params = []

            if surname:
                where_clauses.append("surname = %s")
                params.append(surname)
            if length:
                where_clauses.append("name_length = %s")
                params.append(length)
            if style:
                where_clauses.append("style = %s")
                params.append(style)
            if start_id:  # 添加 start_id 条件
                where_clauses.append("id >= %s")
                params.append(start_id)


            where_clause = " AND ".join(where_clauses)
            query = f"SELECT * FROM names WHERE {where_clause} ORDER BY id LIMIT 500"

            names = await self.db.fetch_all(query, tuple(params))

            if not names:
                logging.info("没有更多需要补全的名字，程序将休眠60秒")
                time.sleep(60)
                continue

            tasks = [
                asyncio.create_task(self.complete_details_for_name(name)) for name in names
            ]
            await asyncio.gather(*tasks)

    async def complete_details_for_name(self, name):
        """补全单个名字的详情"""
        prompt = self.generate_prompt(name)
        logging.info(f"正在补全名字：{name['name']}")
        async with self.semaphore:
            try:
                messages = [
                    {"role": "system", "content": SYSTEM_MESSAGE},
                    {"role": "user", "content": prompt}
                ]
                details = await self.ai_client.chat(messages)

                if details:
                    # 提取 missing_elements
                    missing_elements = self.extract_missing_elements(details)

                     # 获取当前时间
                    now = datetime.datetime.now()

                    await self.db.execute(
                        "UPDATE names SET explanation = %s, is_ready = 1, missing_elements = %s, updated_at = %s WHERE id = %s",  # 添加 updated_at
                        (json.dumps(details, ensure_ascii=False), json.dumps(missing_elements, ensure_ascii=False), now, name['id'])  # 传递 now
                    )
                    logging.info(f"已补全名字详情：{name['name']}")
                else:
                    logging.warning(f"补全名字详情失败：{name['name']}")

            except APIStatusError as e:
                print(f"----- 豆包 AI API 错误 -----")
                print(f"状态码: {e.status_code}")
                print(f"错误类型: {e.type}")
                print(f"错误消息: {e.message}")
                print(f"错误详情: {e.response}")
                print("----------------------------")
            except Exception as e:
                logging.error(f"补全名字时出错：{name['name']}, {e}")

    def extract_missing_elements(self, details):
        """从 details 中提取五行属性"""
        try:
            five_elements_analysis = details.get('five_elements_and_eight_characters_analysis', {})
            five_elements_text = five_elements_analysis.get('five_elements', '')

            # 使用正则表达式提取五行属性
            match = re.findall(r"'(.*?)'属(.)", five_elements_text)  # 匹配 '...'属x 的模式
            missing_elements = []
            element_mapping = {'火':'火','木':'木','土':'土','金':'金','水':'水'}
            if match:
                for item, element in match:
                    if element in element_mapping:
                         missing_elements.append(element_mapping[element])

            return missing_elements
        except Exception as e:
            logging.error(f"提取五行属性时出错: {e}")
            return []

    def generate_prompt(self, name):
        """生成用于补全名字详情的 prompt"""
        prompt = f"""
你的任务是为给定的名字生成一系列相关信息，以便用于开发给孩子取名字的小程序。你需要提供一个名字，性别要求为{name['gender']}，姓名为 {name['name']}，总长度为 {name['name_length']}，风格为 {name['style']}。请注意不要生成以下名字:[]，并且需要输出这个名字以及以下相关信息，方便前端调用，格式为json。以下是具体要求：

    1. **名字含义**
       - 对名字中每个字进行含义分析，包括象征意义。最后给出整体含义。
    2. **文化背景**
       - 查找名字中每个字在中国传统文化中的含义或与之相关的文化典故。
    3. **流行趋势**
       - 分析这个名字在近年来的流行程度，以及在地域方面是否有特殊情况。
    4. **同名名人**
       - 查找是否有知名人物同名，如果没有，提及名字在民间故事或文学作品中的情况。
    5. **音韵分析**
       - 写出名字的发音、音调，分析是否有谐音，以及读起来的感觉，例如是否富有节奏感、是否易于记忆和传播。
    6. **字形分析**
       - 分析名字中每个字的笔画数、结构，以及整体字形的平衡感、书写的流畅性。
    7. **五行八字分析（可选）**
       - 如果可以，分析名字的五行属性，判断是否五行搭配平衡，适合哪些八字情况。并给出吉祥寓意。
    8. **昵称或变体**
       - 给出这个名字可能的昵称和变体。
    9. **诗词或文学引用**
       - 查找是否有包含这个名字或者能体现这个名字含义的诗词或文学俗语,**请给出多条（至少3条）**。
    10. **国际化版本**
       - 给出这个名字的英文名（如果是直译也要注明），并分析在其他语言中的含义情况，如果有相似含义的表达也可提及。
    11. **幸运元素**
       - 给出这个名字的幸运色、幸运数字和幸运宝石，并简单说明理由（如果有）。

    最后，请按照json格式输出结果，例如：
   {{
      "name": "铁柱",
      "name_meaning": {{
         "铁": "代表坚强、刚毅和不屈不挠的精神。",
         "柱": "寓意支柱、依靠，象征稳定和可靠。",
         "整体": "一个坚强有力、值得信赖的人。"
      }},
      "cultural_background": {{
         "铁柱": "在中国传统文化中常用来形容坚固、不可动摇的事物，如'铁柱擎天'。"
      }},
      "popular_trend": {{
         "铁柱": "近年来，'铁柱'这个名字较为少见，具有独特性和复古感。"
      }},
      "famous_namesake": {{
         "铁柱": "暂无知名人物同名，但'铁柱'作为名字在民间故事和文学作品中常出现，象征坚韧不拔的精神。"
      }},
      "phonetic_analysis": {{
         "pronunciation": "Tiě Zhù",
         "tone": "平仄搭配，读起来铿锵有力，富有节奏感。",
         "homophone": "无不良谐音，易于记忆和传播。"
      }},
      "glyph_analysis": {{
         "铁": "10画，结构稳重。",
         "柱": "9画，字形端正。",
         "整体": "整体字形平衡，笔画数适中，书写流畅。"
      }},
      "five_elements_and_eight_characters_analysis": {{
         "five_elements": "名字中'铁'属金，'柱'属木，五行搭配平衡，适合八字缺金或木的孩子。",
         "auspicious_meaning": "名字蕴含金木之力，象征坚韧与成长。"
      }},
      "nickname_or_variant": {{
         "nickname": ["铁柱","柱子"],
         "variant": ["铁铮","铁强"]
      }},
      "poetry_or_literature_quotation": [
        "铁柱擎天，气冲霄汉。——象征力量和雄心壮志。",
        "铁打的柱，永不弯曲。——民间俗语，寓意坚强。"
      ],
      "international_version": {{
         "english_name": "Iron Pillar（直译）",
         "other_languages": "无直接对应版本，但'Iron'和'Pillar'在英语中均有坚强、支柱的含义。"
      }},
      "lucky_elements": {{
         "lucky_color": "金色",
         "lucky_number": "5",
         "lucky_gem": "绿松石（象征坚韧与成功）"
      }}
   }}
"""
        return prompt